/*******************************************************************************
 * The MOSES project, model based software engineering of networked embedded systems.
 * 
 * Copyright (C) 2010-2013, University of Applied Sciences Wildau,
 * Telematics Research Group, http://www.tm.th-wildau.de/research-group
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 3 of the
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <http://www.gnu.org/licenses>.
 * 
 * Contributors:
 *     University of Applied Sciences Wildau - initial API and implementation
 * 
 * If you are interested in a commercial license please contact us via 
 * e-mail: ralf.vandenhouten@th-wildau.de.
 ******************************************************************************/
package de.thwildau.tm.moses.examples.nmea.data;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;

import de.thwildau.tm.moses.abnf.io.AbnfCoder;

/**
 * The GP-RMC (Recommended Minimum Navigation Information) class of NMEA.
 * <p>
 * The structure is:
 * 
 * <pre>
 *  
 *         1      2 3        4 5         6 7     8     9      10    11
 *  $GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A
 *         |      | |        | |         | |     |     |      |     |
 *         |      | |        | |         | |     |     |      |     Variation sign
 *         |      | |        | |         | |     |     |      Variation value
 *         |      | |        | |         | |     |     Date DDMMYY
 *         |      | |        | |         | |     COG
 *         |      | |        | |         | SOG
 *         |      | |        | |         Longitude Sign
 *         |      | |        | Longitude Value
 *         |      | |        Latitude Sign
 *         |      | Latitude value
 *         |      Active or Void
 *         UTC
 * </pre>
 * 
 * Another decription from http://www.nmea.de/nmea0183datensaetze.html:
 * 
 * <pre>
 *                                                             12
 *         1         2 3       4 5        6 7   8   9    10  11|
 *         |         | |       | |        | |   |   |    |   | |
 *  $--RMC,hhmmss.ss,A,llll.ll,a,yyyyy.yy,a,x.x,x.x,xxxx,x.x,a*hh<CR><LF>
 * 
 *  Field Number: 
 *   1) UTC Time
 *   2) Status, V = Navigation receiver warning
 *   3) Latitude
 *   4) N or S
 *   5) Longitude
 *   6) E or W
 *   7) Speed over ground, knots
 *   8) Track made good, degrees true
 *   9) Date, ddmmyy
 *  10) Magnetic Variation, degrees
 *  11) E or W
 *  12) Checksum
 * 
 * </pre>
 * 
 * </p>
 * 
 * @author Thomas Kistel
 * @version $Revision: 764 $
 */
public class GpRmc extends Nmea {

    private Float utcTime;
    private GpRmcStatus status;
    private Float latitude;
    private LatitudeOrientation latitudeOrientation;
    private Float longitude;
    private LongitudeOrientation longitudeOrientation;
    private Float speedOverGround;
    private Float trackMadeGood;
    private Integer date;
    private Float magneticVariation;
    private LongitudeOrientation magneticVariationSign;


    public Float getUtcTime() {
        return utcTime;
    }

    public void setUtcTime(Float utcTime) {
        this.utcTime = utcTime;
    }

    public GpRmcStatus getStatus() {
        return status;
    }

    public void setStatus(GpRmcStatus status) {
        this.status = status;
    }

    public Float getLatitude() {
        return latitude;
    }

    public void setLatitude(Float latitude) {
        this.latitude = latitude;
    }

    public LatitudeOrientation getLatitudeOrientation() {
        return latitudeOrientation;
    }

    public void setLatitudeOrientation(LatitudeOrientation latitudeOrientation) {
        this.latitudeOrientation = latitudeOrientation;
    }

    public Float getLongitude() {
        return longitude;
    }

    public void setLongitude(Float longitude) {
        this.longitude = longitude;
    }

    public LongitudeOrientation getLongitudeOrientation() {
        return longitudeOrientation;
    }

    public void setLongitudeOrientation(LongitudeOrientation longitudeOrientation) {
        this.longitudeOrientation = longitudeOrientation;
    }

    public Float getSpeedOverGround() {
        return speedOverGround;
    }

    public void setSpeedOverGround(Float speedOverGround) {
        this.speedOverGround = speedOverGround;
    }

    public Float getTrackMadeGood() {
        return trackMadeGood;
    }

    public void setTrackMadeGood(Float trackMadeGood) {
        this.trackMadeGood = trackMadeGood;
    }

    public Integer getDate() {
        return date;
    }

    public void setDate(Integer date) {
        this.date = date;
    }

    public Float getMagneticVariation() {
        return magneticVariation;
    }

    public void setMagneticVariation(Float magneticVariation) {
        this.magneticVariation = magneticVariation;
    }

    public LongitudeOrientation getMagneticVariationSign() {
        return magneticVariationSign;
    }

    public void setMagneticVariationSign(LongitudeOrientation magneticVariationSign) {
        this.magneticVariationSign = magneticVariationSign;
    }

    @Override
    public void read(DataInput in) throws IOException {
        this.utcTime = AbnfCoder.decodeUntil(in, ",", Float.class);
        this.status = AbnfCoder.decode(in, GpRmcStatus.values());
        AbnfCoder.checkDecode(in, ",");
        this.latitude = AbnfCoder.decodeUntil(in, ",", Float.class);
        this.latitudeOrientation = AbnfCoder.decode(in, LatitudeOrientation.values());
        AbnfCoder.checkDecode(in, ",");
        this.longitude = AbnfCoder.decodeUntil(in, ",", Float.class);
        this.longitudeOrientation = AbnfCoder.decode(in, LongitudeOrientation.values());
        AbnfCoder.checkDecode(in, ",");
        this.speedOverGround = AbnfCoder.decodeUntil(in, ",", Float.class);
        this.trackMadeGood = AbnfCoder.decodeUntil(in, ",", Float.class);
        this.date = AbnfCoder.decodeUntil(in, ",", Integer.class);
        this.magneticVariation = AbnfCoder.decodeUntil(in, ",", Float.class);
        this.magneticVariationSign = AbnfCoder.decode(in, LongitudeOrientation.values());
        AbnfCoder.checkDecode(in, "*");
        String checksum = AbnfCoder.decode(in, 2);
        this.checksum = Integer.valueOf(checksum, 16);
    }

    @Override
    public void write(DataOutput out) throws IOException {
        throw new UnsupportedOperationException("Not implemented.");
        // AbnfCoder.encode(out, "$");
        // AbnfCoder.encode(out, alphas);
        // AbnfCoder.encode(out, ",");
        // AbnfCoder.encode(out, Float.toString(time));
        // AbnfCoder.encode(out, ",");
        // AbnfCoder.encode(out, status);
        // AbnfCoder.encode(out, ",");
        // AbnfCoder.encode(out, Float.toString(latitude));
        // AbnfCoder.encode(out, ",");
        // AbnfCoder.encode(out, latns);
        // AbnfCoder.encode(out, ",");
        // AbnfCoder.encode(out, Float.toString(longitude));
        // AbnfCoder.encode(out, ",");
        // AbnfCoder.encode(out, lonew);
        // AbnfCoder.encode(out, ",");
        // AbnfCoder.encode(out, Float.toString(speed));
        // AbnfCoder.encode(out, ",");
        // AbnfCoder.encode(out, Float.toString(direction));
        // AbnfCoder.encode(out, ",");
        // AbnfCoder.encode(out, date);
        // AbnfCoder.encode(out, ",");
        // AbnfCoder.encode(out, Float.toString(kom));
        // AbnfCoder.encode(out, ",");
        // AbnfCoder.encode(out, komew);
        // AbnfCoder.encode(out, ",");
        // AbnfCoder.encode(out, art);
        // AbnfCoder.encode(out, "*");
        // AbnfCoder.encode(out, checkSum);
        // AbnfCoder.encode(out, CoreRules.CRLF);
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("$GPRMC");
        builder.append(",").append(utcTime);
        builder.append(",").append(status);
        builder.append(",").append(latitude);
        builder.append(",").append(latitudeOrientation);
        builder.append(",").append(longitude);
        builder.append(",").append(longitudeOrientation);
        builder.append(",").append(speedOverGround);
        builder.append(",").append(trackMadeGood);
        builder.append(",").append(date);
        builder.append(",").append(magneticVariation);
        builder.append(",").append(magneticVariationSign);
        return builder.toString();
    }
}
